package models

import (
	"fmt"
	"ginstudydemo.com/main/dao"
	"strconv"
	"strings"
)

type IResourceModel interface {
	CreateTestDataHandler()
}

type ResourceModel struct{}

func NewResourceModel() *ResourceModel {
	return &ResourceModel{}
}

// GetUsePageByCate 分页获取指定分类资源数据
func (u ResourceModel) GetUsePageByCate(query ResourcePageByCateParams, pageParams PaginationParams) ([]ResourceRes, int64, int, int, error) {
	resources := make([]ResourceRes, 0)

	model := dao.Db.Debug().Table("resource r").
		Select("r.*, ct.name as category_name, rt.name as resource_type_name,t.id as topic_id, t.title as topic_title,JSON_UNQUOTE(JSON_EXTRACT(r.tags, '$[*]')) as tags").
		Joins("LEFT JOIN content_type ct ON r.category_id = ct.id").
		Joins("LEFT JOIN resource_type rt ON r.resource_type = rt.id").
		Joins("LEFT JOIN topic_resource tr ON r.id = tr.resource_id").
		Joins("LEFT JOIN topic t ON tr.topic_id = t.id").
		Where("r.is_deleted = ?", 0)

	// 是否获取子集分类数据
	if query.IsSubCate {
		var flatCategories []CategoryAndResRecursionData
		categoryIDsRECURSIVE := strings.Split(query.CategoryId, ",")

		errRECURSIVE := dao.Db.Debug().Raw(`
        WITH RECURSIVE cte AS (
            SELECT * FROM content_type WHERE id IN ?
            UNION ALL
            SELECT c.* FROM content_type c
            INNER JOIN cte ON c.parent_id = cte.id
        )
        SELECT * FROM cte WHERE is_deleted = 0;
    `, categoryIDsRECURSIVE).Scan(&flatCategories).Error
		if errRECURSIVE != nil {
			return nil, 0, 0, 0, errRECURSIVE
		}

		if len(flatCategories) == 0 {
			return nil, 0, 0, 0, nil
		}

		var categoryIDs []int64
		for _, cat := range flatCategories {
			categoryIDs = append(categoryIDs, cat.ID)
		}

		strNums := make([]string, len(categoryIDs))
		for i, num := range categoryIDs {
			strNums[i] = strconv.Itoa(int(num))
		}
		categoryIDsStr := strings.Join(strNums, ",")

		if categoryIDsStr != "" {
			categoryIDs := strings.Split(categoryIDsStr, ",")
			model = model.Where("r.category_id IN ?", categoryIDs)
		}
	} else {
		if query.CategoryId != "" {
			categoryIDs := strings.Split(query.CategoryId, ",")
			model = model.Where("r.category_id IN ?", categoryIDs)
		}
	}

	// 资源类型筛选
	if query.ResourceType != "" {
		model = model.Where("r.resource_type = ?", query.ResourceType)
	}

	// 关键词筛选
	if query.Keyword != "" {
		model = model.Where("r.title LIKE ?", "%"+query.Keyword+"%")
	}

	// 获取总数
	var total int64
	if err := model.Count(&total).Error; err != nil {
		return nil, 0, 0, 0, err
	}

	// 添加分页条件
	offset := (pageParams.PageNum - 1) * pageParams.PageSize
	model = model.Limit(pageParams.PageSize).Offset(offset)

	// 执行查询获取分页数据
	if err := model.Scan(&resources).Error; err != nil {
		return resources, 0, 0, 0, err
	}

	// 如果传入了userId，查询用户的点赞和收藏状态
	if query.UserID != "" {
		userId, err := strconv.ParseInt(query.UserID, 10, 64)
		if err != nil {
			return nil, 0, 0, 0, fmt.Errorf("invalid user id")
		}

		// 获取所有资源ID
		var resourceIDs []uint
		for _, res := range resources {
			resourceIDs = append(resourceIDs, res.ID)
		}

		// 批量查询点赞状态
		likeMap := make(map[uint]bool)
		if len(resourceIDs) > 0 {
			var likes []struct {
				TargetID uint
			}
			err := dao.Db.Table("user_like").
				Select("target_id").
				Where("user_id = ? AND target_id IN ? AND target_type = ? AND is_deleted = 0",
					userId, resourceIDs, 1). // 1表示资源类型
				Find(&likes).Error
			if err != nil {
				return nil, 0, 0, 0, err
			}
			for _, like := range likes {
				likeMap[like.TargetID] = true
			}
		}

		// 批量查询收藏状态
		collectMap := make(map[uint]bool)
		if len(resourceIDs) > 0 {
			var collects []struct {
				ResourceID uint
			}
			err := dao.Db.Table("user_collect").
				Select("resource_id").
				Where("user_id = ? AND resource_id IN ? AND is_deleted = 0",
					userId, resourceIDs).
				Find(&collects).Error
			if err != nil {
				return nil, 0, 0, 0, err
			}
			for _, collect := range collects {
				collectMap[collect.ResourceID] = true
			}
		}

		// 设置isLike和isCollect字段
		for i := range resources {
			resources[i].IsLike = likeMap[resources[i].ID]
			resources[i].IsCollect = collectMap[resources[i].ID]
		}
	}

	return resources, total, pageParams.PageNum, pageParams.PageSize, nil
}

// GetUserViewHistory 分页获取用户浏览历史（不去重版本）
func (u ResourceModel) GetUserViewHistory(query GetUserViewHistoryParams, pageParams PaginationParams) ([]ViewHistoryResourceRes, int64, int, int, error) {
	resources := make([]ViewHistoryResourceRes, 0)

	// 强化用户ID验证
	if query.UserID <= 0 {
		return nil, 0, 0, 0, fmt.Errorf("无效的用户ID")
	}

	// 直接基于浏览记录表查询
	model := dao.Db.Debug().Table("resource_view_log rvl").
		Select(`
            rvl.id as view_log_id,
            rvl.resource_id,
            rvl.create_time,
            r.title,
            r.cover_image,
            r.card_cover_image,
            r.banner_cover_image,
            r.resource_type,
            r.category_id,
            r.view_count,
            r.like_count,
            r.collect_count,
            r.introduction,
            r.web_url,
            r.media_url,
            r.release_date,
            ct.name as category_name,
            rt.name as resource_type_name,
            JSON_UNQUOTE(JSON_EXTRACT(r.tags, '$[*]')) as tags
        `).
		Joins("INNER JOIN resource r ON rvl.resource_id = r.id").
		Joins("LEFT JOIN content_type ct ON r.category_id = ct.id").
		Joins("LEFT JOIN resource_type rt ON r.resource_type = rt.id").
		Where("rvl.user_id = ?", query.UserID). // 确保只能查询自己的记录
		Where("r.is_deleted = 0").
		Order("rvl.create_time DESC") // 按浏览时间倒序

	//// 分类处理逻辑
	//if query.CategoryID != "" {
	//	categoryIDs := make([]int64, 0)
	//	rawIDs := strings.Split(query.CategoryID, ",")
	//
	//	for _, idStr := range rawIDs {
	//		id, err := strconv.ParseInt(idStr, 10, 64)
	//		if err != nil || id <= 0 {
	//			continue
	//		}
	//
	//		if query.IsSubCate {
	//			var subIDs []struct{ ID int64 }
	//			dao.Db.Raw(`
	//                WITH RECURSIVE cte AS (
	//                    SELECT id FROM content_type
	//                    WHERE id = ? AND is_deleted = 0
	//                    UNION ALL
	//                    SELECT c.id FROM content_type c
	//                    INNER JOIN cte ON c.parent_id = cte.id
	//                    WHERE c.is_deleted = 0
	//                )
	//                SELECT id FROM cte
	//            `, id).Scan(&subIDs)
	//
	//			for _, s := range subIDs {
	//				categoryIDs = append(categoryIDs, s.ID)
	//			}
	//		} else {
	//			categoryIDs = append(categoryIDs, id)
	//		}
	//	}
	//
	//	if len(categoryIDs) > 0 {
	//		model = model.Where("r.category_id IN (?)", categoryIDs)
	//	}
	//}

	// 是否获取子集分类数据
	if query.IsSubCate {
		var flatCategories []CategoryAndResRecursionData
		categoryIDsRECURSIVE := strings.Split(query.CategoryID, ",")

		errRECURSIVE := dao.Db.Debug().Raw(`
        WITH RECURSIVE cte AS (
            SELECT * FROM content_type WHERE id IN ?
            UNION ALL
            SELECT c.* FROM content_type c
            INNER JOIN cte ON c.parent_id = cte.id
        )
        SELECT * FROM cte WHERE is_deleted = 0;
    `, categoryIDsRECURSIVE).Scan(&flatCategories).Error
		if errRECURSIVE != nil {
			return nil, 0, 0, 0, errRECURSIVE
		}

		if len(flatCategories) == 0 {
			return nil, 0, 0, 0, nil
		}

		var categoryIDs []int64
		for _, cat := range flatCategories {
			categoryIDs = append(categoryIDs, cat.ID)
		}

		fmt.Println("=== Final categoryIDs ===")
		fmt.Printf("Total IDs: %d\n", len(categoryIDs))
		fmt.Printf("IDs list: %v\n", categoryIDs)
		fmt.Println("=========================")

		strNums := make([]string, len(categoryIDs))
		for i, num := range categoryIDs {
			strNums[i] = strconv.Itoa(int(num))
		}
		categoryIDsStr := strings.Join(strNums, ",")

		if categoryIDsStr != "" {
			categoryIDs := strings.Split(categoryIDsStr, ",")
			model = model.Where("r.category_id IN ?", categoryIDs)
		}
	} else {
		if query.CategoryID != "" {
			fmt.Printf("IDs list: %s\n", query.CategoryID)

			categoryIDs := strings.Split(query.CategoryID, ",")
			model = model.Where("r.category_id IN ?", categoryIDs)
		}
	}

	// 资源类型校验
	if query.ResourceType != 0 {
		if query.ResourceType < 1 || query.ResourceType > 4 {
			return nil, 0, 0, 0, fmt.Errorf("无效的资源类型")
		}
		model = model.Where("r.resource_type = ?", query.ResourceType)
	}

	// 关键词过滤
	if query.Keyword != "" {
		safeKeyword := strings.ReplaceAll(query.Keyword, "%", "")
		model = model.Where("r.title LIKE ?", "%"+safeKeyword+"%")
	}

	// 获取总数
	var total int64
	if err := model.Count(&total).Error; err != nil {
		return nil, 0, 0, 0, err
	}

	// 分页处理
	if pageParams.PageNum < 1 || pageParams.PageSize < 1 {
		return nil, 0, 0, 0, fmt.Errorf("分页参数错误")
	}
	offset := (pageParams.PageNum - 1) * pageParams.PageSize
	model = model.Offset(int(offset)).Limit(int(pageParams.PageSize))

	// 执行查询
	if err := model.Scan(&resources).Error; err != nil {
		return nil, 0, 0, 0, err
	}

	// 关联用户状态
	if len(resources) > 0 {
		resourceIDs := make([]uint, 0, len(resources))
		for _, res := range resources {
			resourceIDs = append(resourceIDs, res.ResourceID)
		}

		// 点赞状态查询
		likeMap := make(map[uint]bool)
		dao.Db.Table("user_like").
			Where("user_id = ? AND target_id IN ? AND target_type = 1 AND is_deleted = 0",
				query.UserID,
				resourceIDs).
			Pluck("target_id", &likeMap)

		// 收藏状态查询
		collectMap := make(map[uint]bool)
		dao.Db.Table("user_collect").
			Where("user_id = ? AND resource_id IN ? AND is_deleted = 0",
				query.UserID,
				resourceIDs).
			Pluck("resource_id", &collectMap)

		// 设置状态
		for i := range resources {
			resources[i].IsLike = likeMap[resources[i].ResourceID]
			resources[i].IsCollect = collectMap[resources[i].ResourceID]
		}
	}

	return resources, total, pageParams.PageNum, pageParams.PageSize, nil
}

// GetUsePageByTopic 分页获取指定专辑下的数据
// GetUsePageByTopic 分页获取指定专辑下的数据
func (u ResourceModel) GetUsePageByTopic(query ResourcePageByTopic, pageParams PaginationParams) ([]ResourceRes, int64, int, int, error) {
	resources := make([]ResourceRes, 0)

	model := dao.Db.Debug().Table("resource r").
		Select("r.*, ct.name as category_name, rt.name as resource_type_name,t.id as topic_id, t.title as topic_title,JSON_UNQUOTE(JSON_EXTRACT(r.tags, '$[*]')) as tags").
		Joins("LEFT JOIN content_type ct ON r.category_id = ct.id").
		Joins("LEFT JOIN resource_type rt ON r.resource_type = rt.id").
		Joins("LEFT JOIN topic_resource tr ON r.id = tr.resource_id").
		Joins("LEFT JOIN topic t ON tr.topic_id = t.id").
		Where("r.is_deleted = ?", 0)

	if query.TopicId != "" {
		model = model.Where("tr.topic_id = ?", query.TopicId)
	}

	// 资源类型筛选
	if query.ResourceType != "" {
		model = model.Where("r.resource_type = ?", query.ResourceType)
	}

	// 关键词筛选
	if query.Keyword != "" {
		model = model.Where("r.title LIKE ?", "%"+query.Keyword+"%")
	}

	// 获取总数
	var total int64
	if err := model.Count(&total).Error; err != nil {
		return nil, 0, 0, 0, err
	}

	// 添加分页条件
	offset := (pageParams.PageNum - 1) * pageParams.PageSize
	model = model.Limit(pageParams.PageSize).Offset(offset)

	// 执行查询获取分页数据
	if err := model.Scan(&resources).Error; err != nil {
		return nil, 0, 0, 0, err
	}

	// 如果传入了userId，查询用户的点赞和收藏状态
	if query.UserID != "" {
		userId, err := strconv.ParseInt(query.UserID, 10, 64)
		if err != nil {
			return nil, 0, 0, 0, fmt.Errorf("invalid user id")
		}

		// 获取所有资源ID
		var resourceIDs []uint
		for _, res := range resources {
			resourceIDs = append(resourceIDs, res.ID)
		}

		// 批量查询点赞状态
		likeMap := make(map[uint]bool)
		if len(resourceIDs) > 0 {
			var likes []struct {
				TargetID uint
			}
			err := dao.Db.Table("user_like").
				Select("target_id").
				Where("user_id = ? AND target_id IN ? AND target_type = ? AND is_deleted = 0",
					userId, resourceIDs, 1). // 1表示资源类型
				Find(&likes).Error
			if err != nil {
				return nil, 0, 0, 0, err
			}
			for _, like := range likes {
				likeMap[like.TargetID] = true
			}
		}

		// 批量查询收藏状态
		collectMap := make(map[uint]bool)
		if len(resourceIDs) > 0 {
			var collects []struct {
				ResourceID uint
			}
			err := dao.Db.Table("user_collect").
				Select("resource_id").
				Where("user_id = ? AND resource_id IN ? AND is_deleted = 0",
					userId, resourceIDs).
				Find(&collects).Error
			if err != nil {
				return nil, 0, 0, 0, err
			}
			for _, collect := range collects {
				collectMap[collect.ResourceID] = true
			}
		}

		// 设置isLike和isCollect字段
		for i := range resources {
			resources[i].IsLike = likeMap[resources[i].ID]
			resources[i].IsCollect = collectMap[resources[i].ID]
		}
	}

	return resources, total, pageParams.PageNum, pageParams.PageSize, nil
}
